from typing import List, Optional
from blog.models import Article, Category, CategoryIn_Py,Category_Py, Category_types
from fastapi import APIRouter, status, Body, Query
from fastapi.responses import JSONResponse
from tortoise import exceptions

router = APIRouter(prefix="/categories", tags=["category"])

@router.post("/", response_model=Category_Py)
async def create_category(category: CategoryIn_Py):
    try:
        category_obj = await Category.create(**category.dict(exclude_unset=True))
    except exceptions.IntegrityError:
        return JSONResponse(content={"error": "duplicated"},  status_code=status.HTTP_400_BAD_REQUEST)
    except ValueError:
        return JSONResponse(content={"error": "invalid type"},  status_code=status.HTTP_400_BAD_REQUEST)
    return await Category_Py.from_tortoise_orm(category_obj)

@router.get("/", response_model=List[Category_Py])
async def get_categories(type:Optional[str]=Query(None, max_length=20)):
    qs = Category.all()
    if type:
        type = type.lower()
        if type in Category_types.__members__.keys():
            qs = qs.filter(type=type)
        else:
            return []
    return await Category_Py.from_queryset(qs)

@router.put("/{id}/", response_model=Category_Py)
async def update_category(id: int, category: CategoryIn_Py):
    try:
        await Category.get(id=id).update(**category.dict(exclude_unset=True))
    except exceptions.IntegrityError as e:
        return JSONResponse(content={"error": "duplicated"},  status_code=status.HTTP_400_BAD_REQUEST)

    try:
        return await Category_Py.from_queryset_single(Category.get(id=id))
    except exceptions.DoesNotExist:
        return JSONResponse(content={"error": "category not found"}, status_code=status.HTTP_404_NOT_FOUND)

@router.delete("/{id}/")
async def delete_category(id: int):
    await Category.get(id=id).delete()

@router.delete("/")
async def delete_categories(ids:List[int]):
    await Category.filter(id__in=ids).delete()
    

@router.post("/{id}/add_articles/")
async def add_articles(id: int, articles: List[int]):
    try:
        await Category.get(id=id)
    except exceptions.DoesNotExist:
        return JSONResponse(content={"error": "category not found"}, status_code=status.HTTP_404_NOT_FOUND)  

    return await Article.all_objects.filter(id__in=articles).update(category_id=id)

